package com.video.cloud.controller;

import com.google.gson.Gson;
import com.qiji.common.api.ResultCode;
import com.qiji.common.exception.ApiException;
import com.sun.deploy.net.URLEncoder;
import com.video.cloud.config.ConstantWxUtils;
import com.video.cloud.config.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/**
 * @author xppll
 * @date 2021/12/11 14:48
 */
@CrossOrigin
@Controller
@RequestMapping("/api/ucenter/wx")
public class WxApiController {
    @Autowired
    private UcenterMemberService memberService;

    /**
     * 生成微信扫描二维码
     * @return 定向到请求微信地址
     */
    @GetMapping("login")
    public String getWxCode() {

        //微信开放平台授权baseUrl
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";


        //对redirect_url进行URLEncoder编码
        String redirectUrl = ConstantWxUtils.WX_OPEN_REDIRECT_URL;
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new ApiException(ResultCode.FAILED);
        }
        //设置%s的值
        String url = String.format(
                baseUrl,
                ConstantWxUtils.WX_OPEN_APP_ID,
                redirectUrl,
                "atguigu"
        );

        //重定向到请求微信地址
        return "redirect:" + url;
    }


    /**
     * 获取扫描人信息，添加数据
     * @param code 类似于手机验证码，随机唯一的值
     * @param state 用于保持请求和回调的状态，授权请求后原样带回给第三方
     * @return
     */
    @GetMapping("callback")
    public String callback(String code, String state) {
        try {
            //获取code值，临时票据类似于验证码
            //拿着code请求微信固定的地址，得到两个值
            //1.向认证服务器发送请求换取access_token
            String baseAccessTokenUrl =
                    "https://api.weixin.qq.com/sns/oauth2/access_token" +
                            "?appid=%s" +
                            "&secret=%s" +
                            "&code=%s" +
                            "&grant_type=authorization_code";
            //拼接三个参数：id 密钥 和 code值
            String accessTokenUrl = String.format(
                    baseAccessTokenUrl,
                    ConstantWxUtils.WX_OPEN_APP_ID,
                    ConstantWxUtils.WX_OPEN_APP_SECRET,
                    code
            );
            //2.请求拼接好的地址，得到返回的两个值access_token和openid
            //使用httpclient发送请求，得到返回结果(json形式的字符串)
            String accessTokenInfo = HttpClientUtils.get(accessTokenUrl);
            //从accessTokenInfo字符串获取两个值access_token、openid
            //把accessTokenInfo字符串转换为map集合，根据map里面的key获取值
            //这里使用json转换工具Gson
            Gson gson = new Gson();
            HashMap accessTokenMap = gson.fromJson(accessTokenInfo, HashMap.class);
            String access_token = (String) accessTokenMap.get("access_token");
            String openid = (String) accessTokenMap.get("openid");

            //3.判断该用户是不是第一次扫码登录
            //通过openid判断
            UcenterMember member = memberService.getOpenIdMember(openid);
            //4.只有第一次登录才获取信息
            if (member == null) {
                //根据access_token和openid再去访问微信的资源服务器，获取用户信息
                String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                        "?access_token=%s" +
                        "&openid=%s";
                String userInfoUrl = String.format(
                        baseUserInfoUrl,
                        access_token,
                        openid
                );
                //发送请求，得到用户信息
                String userInfo = HttpClientUtils.get(userInfoUrl);
                System.out.println(userInfo);
                //将用户信息存入数据库
                //把json转换为map
                HashMap userInfoMap = gson.fromJson(userInfo, HashMap.class);
                //得到nickname
                String nickname = (String) userInfoMap.get("nickname");
                //得到微信头像avatar
                String headimgurl = (String) userInfoMap.get("headimgurl");

                member = new UcenterMember();
                member.setOpenid(openid);
                member.setNickname(nickname);
                member.setAvatar(headimgurl);
                memberService.save(member);
            }
            //5.使用jwt根据member对象生成token字符串
            String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());

            //最后返回首页面，通过路径传递token字符串
            return "redirect:http://localhost:3000?token=" + jwtToken;
        } catch (Exception e) {
            throw new GuliException(20001, "微信登录失败");
        }
    }
    /**
     * 根据openid查询是否存在用户
     * @param openid 授权用户唯一标识
     * @return UcenterMember
     */
    @Override
    public UcenterMember getOpenIdMember(String openid) {
        LambdaQueryWrapper<UcenterMember> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(UcenterMember::getOpenid,openid);
        UcenterMember member = baseMapper.selectOne(queryWrapper);
        return member;
    }


}
